/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#ifndef SBJ_Arrow_QueueStats_h
#define SBJ_Arrow_QueueStats_h

#include "SBJ/Time/Stat.h"

namespace SBJ
{

namespace Arrow
{

class DequeueStat
{
public:
	struct Result
	{
		int sleeps;
		Stat<>::Result time;
	};

	DequeueStat( void ) {}
	
	void accumeSleep( void ) { ++m_sleep; }
	void accumeRouted( void ) { m_time.accume(); }

	void start( void )
	{
		m_sleep = 0;
		m_time.start();
	}

	void stop( void )
	{
		m_time.stop();
	}

	Result getResult( void ) const
	{
		Result r = { m_sleep, m_time.getResult() };
		return r;
	}

private:
	int m_sleep;
	Stat<> m_time;
};

class EnqueueStat
{
public:
	struct Result
	{
		int hits;
		int discoveries;
		int consumptions;
		int collisions;
		int reused;
		int variants;
		int independents;
		int allocations;
		int dropped;
		int invalid;
		int available;
		Stat<>::Result time;
	};

	EnqueueStat( void ) {}
	
	void accumeDiscovery( void ) { ++m_discovery; m_time.accume(); }
	void accumeConsume( void ) { ++m_consume; m_time.accume(); }
	void accumeCollision( void ) { ++m_collision; m_time.accume(); }
	void accumeReuse( void ) { ++m_reuse; m_time.accume(); }
	void accumeVariant( void ) { ++m_variant; m_time.accume(); }
	void accumeIndependent( void ) { ++m_independent; m_time.accume(); }
	void accumeDrop( void ) { ++m_drop; }
	void accumeInvalid( void ) { ++m_invalid; }

	void start( void )
	{
		m_discovery = 0;
		m_consume = 0;
		m_collision = 0;
		m_reuse = 0;
		m_variant = 0;
		m_independent = 0;
		m_drop = 0;
		m_invalid = 0;
		m_time.start();
	}

	void stop( void )
	{
		m_time.stop();
	}

	Result getResult( void ) const
	{
		Result r = { m_time.getResult().total + m_drop,
					 m_discovery, m_consume, m_collision, m_reuse, m_variant, m_independent,
					 m_discovery + m_collision + m_variant + m_independent, m_drop, m_invalid,
					 m_time.getResult().total - m_consume, // avail
					 m_time.getResult() };
		return r;
	}

private:
	int m_discovery;
	int m_consume;
	int m_collision;
	int m_reuse;
	int m_variant;
	int m_independent;
	int m_drop;
	int m_invalid;
	Stat<> m_time;
};

}

}

#endif